package com.haust.search.service.impl;

import com.haust.commons.pojo.HaustResult;
import com.haust.search.dao.SearchDao;
import com.haust.search.feign.BackendItemFeignInterface;
import com.haust.search.pojo.SearchItem;
import com.haust.search.service.SearchService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class SearchServiceImpl implements SearchService {
    @Autowired
    private BackendItemFeignInterface backendItemFeignInterface;

    @Autowired
    private SearchDao searchDao;

    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * openfeign技术，远程服务调用的返回结果，如果是引用类型，是基于jackson实现
     * 数据转换处理的。
     * 如果远程服务返回的数据，是多层封装。集合中的元素一定是LinkHashMap类型的对象。
     * 远程返回 List<A>, 客户端得到的集合类型是 List<A>
     * 远程返回的是  A{ List<B> }, 客户端得到的类型是  A { List<LinkHashMap> }
     * <p>
     * 初始化
     * 1. openfeign远程调用后台的商品服务
     * 2. 访问ES，创建索引，设置映射
     * 3. 保存商品数据到ES。
     *
     * @return
     */
    @Override
    public HaustResult init() {
        // 远程调用后台商品服务。查询商品
        HaustResult result =
                backendItemFeignInterface.getAll4Search();
        List<Map<String, Object>> data = (List<Map<String, Object>>) result.getData();

        List<SearchItem> searchItems = new ArrayList<>(data.size());
        try {
            for (Map<String, Object> m : data) {
                //怎么将Map转化为对象
                //1、将Map对象转化为Jackson对象
                String json = objectMapper.writeValueAsString(m);
                //2、将Jackson对象转化为java对象
                SearchItem searchItem = objectMapper.readValue(json, SearchItem.class);
                searchItems.add(searchItem);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return HaustResult.error("服务忙，请骚后！");
        }


        //创建索引
        searchDao.createIndex();

        //索引映射
        searchDao.putMapping();

        //批量保存
        searchDao.batchSave(searchItems);

        return HaustResult.ok();
    }

    /**
     * 分页搜索
     *
     * @param q    搜索条件
     *             必须存在数据。保证没有魔鬼搜索。
     *             校验搜索条件必须存在，且有数据，如果不符合约束，则返回拖地数据
     *             条件在字段商品标题、商品买点、商品分类名称中should+match匹配
     * @param page 第几页
     * @param rows 多少页
     * @return
     */
    @Override
    public HaustResult list(String q, Integer page, Integer rows) {
        if (q == null && q.trim().length() == 0) {
            return HaustResult.error("搜索结果不存在，请输入有效数据");
        }

        Map<String, Object> search = searchDao.search(q, page, rows);
        return HaustResult.ok(search);
    }

    @Override
    public HaustResult removeById(Long itemId) {
        searchDao.removeById(itemId);
        return HaustResult.ok();
    }

    @Override
    public HaustResult add(Map<String, Object> item) {

        SearchItem searchItem = null;

        try {
            searchItem = objectMapper.readValue(
                    objectMapper.writeValueAsString(item),
                    SearchItem.class
            );
        } catch (Exception e) {
            e.printStackTrace();
           return HaustResult.error("服务忙，稍后重试");
        }
        searchDao.save(searchItem);
        return HaustResult.ok();
    }
}
